1
/****************************** Module Header *********************************************************\
2 * Module Name: OpenOtherWorkItemControl
3 * Project: CSTFSCustomWorkItemControl
4 * Copyright (c) Microsoft Corporation.
6 * The OpenOtherWorkItemControl demonstrates how to create and deploy a Custom WorkItem Control which
7 * open another work item in Visual Studio.
9 * This source is subject to the Microsoft Public License.
10 * See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
11 * All other rights reserved.
13 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
14 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
16 \********************************************************************************************************/
20 #region Using Directive
22 using System
.Collections
.Generic
;
25 using System
.Windows
.Forms
;
27 using Microsoft
.TeamFoundation
.WorkItemTracking
.Controls
;
28 using System
.ComponentModel
;
29 using Microsoft
.TeamFoundation
.WorkItemTracking
.Client
;
30 using System
.Collections
.Specialized
;
31 using Microsoft
.VisualStudio
.TeamFoundation
;
32 using Microsoft
.TeamFoundation
.Client
;
33 using Microsoft
.VisualStudio
.TeamFoundation
.WorkItemTracking
;
36 namespace CSTFSCustomWorkItemControl
38 public class OpenOtherWorkItemControl
: UserControl
, IWorkItemControl
40 #region InitializeUIComponent
42 public OpenOtherWorkItemControl()
44 InitializeComponent();
50 private void InitializeComponent()
52 this.tb1
= new System
.Windows
.Forms
.TextBox();
53 this.btn1
= new System
.Windows
.Forms
.Button();
58 this.tb1
.Location
= new System
.Drawing
.Point(4, 2);
59 this.tb1
.Name
= "tb1";
60 this.tb1
.Size
= new System
.Drawing
.Size(100, 20);
61 this.tb1
.TabIndex
= 0;
65 this.btn1
.Location
= new System
.Drawing
.Point(111, 0);
66 this.btn1
.Name
= "btn1";
67 this.btn1
.Size
= new System
.Drawing
.Size(66, 23);
68 this.btn1
.TabIndex
= 1;
69 this.btn1
.Text
= "Open";
70 this.btn1
.UseVisualStyleBackColor
= true;
71 this.btn1
.Click
+= new System
.EventHandler(this.btn1_Click
);
73 // OpenOtherWorkItemControl
75 this.Controls
.Add(this.btn1
);
76 this.Controls
.Add(this.tb1
);
77 this.Name
= "OpenOtherWorkItemControl";
78 this.Size
= new System
.Drawing
.Size(180, 25);
79 this.ResumeLayout(false);
85 #region Fields and properties
87 private EventHandlerList m_events
;
88 private EventHandlerList Events
94 m_events
= new EventHandlerList();
100 private static object EventBeforeUpdateDatasource
= new object();
101 private static object EventAfterUpdateDatasource
= new object();
103 private StringDictionary m_properties
;
104 private bool m_readOnly
;
105 private IServiceProvider m_serviceProvider
;
106 private WorkItem m_workItem
;
107 private string m_fieldName
;
110 /// The top-level object in the Visual Studio automation object model.
119 //Get Visual Studio automation object model from m_serviceProvider
120 var vsModel
= m_serviceProvider
.GetService(typeof(EnvDTE
.DTE
));
121 dte2
= (EnvDTE80
.DTE2
)vsModel
;
128 #region IWorkItemControl Members
131 /// Raise this events before updating WorkItem object with values. When value is changed
132 /// by a control, work item form asks all controls (except current control) to refresh their display
133 /// values (by calling InvalidateDatasource) in case if affects other controls
135 public event EventHandler BeforeUpdateDatasource
137 add { Events.AddHandler(EventBeforeUpdateDatasource, value); }
138 remove { Events.RemoveHandler(EventBeforeUpdateDatasource, value); }
141 /// Raise this event after updating WorkItem object with values. When value is changed
142 /// by a control, work item form asks all controls (except current control) to refresh their display
143 /// values (by calling InvalidateDatasource) in case if affects other controls
145 public event EventHandler AfterUpdateDatasource
147 add { Events.AddHandler(EventAfterUpdateDatasource, value); }
148 remove { Events.RemoveHandler(EventAfterUpdateDatasource, value); }
152 /// Control is asked to clear its contents
154 void IWorkItemControl
.Clear()
156 tb1
.Text
= string.Empty
;
160 /// Control is requested to flush any data to workitem object.
162 void IWorkItemControl
.FlushToDatasource()
167 /// Asks control to invalidate the contents and redraw.
169 void IWorkItemControl
.InvalidateDatasource()
174 /// All attributes specified in work item type definition file for this control, including custom attributes
176 StringDictionary IWorkItemControl
.Properties
184 m_properties
= value;
189 /// Whether the control is readonly.
191 bool IWorkItemControl
.ReadOnly
204 /// Gives pointer to IServiceProvider if you have to use VS Services.
206 void IWorkItemControl
.SetSite(IServiceProvider serviceProvider
)
208 m_serviceProvider
= serviceProvider
;
212 /// WorkItemDatasource refers to current work item object.
214 object IWorkItemControl
.WorkItemDatasource
222 m_workItem
= (WorkItem
)value;
224 //WorkItem.FieldChanged event is very useful, and it will be fired when the value
225 // of other field changed
226 //m_workItem.FieldChanged+=new WorkItemFieldChangeEventHandler(m_workItem_FieldChanged);
231 /// The field name which the control is associated with in work item type definition.
233 string IWorkItemControl
.WorkItemFieldName
246 #region Private funtions
249 /// Returen the instance of TeamFoundationServerExt, from which we can get current
250 /// TFS ActiveProjectContext
252 private TeamFoundationServerExt
GetTFSExt()
254 TeamFoundationServerExt tfsExt
= DTE2
.GetObject("Microsoft.VisualStudio.TeamFoundation.TeamFoundationServerExt") as TeamFoundationServerExt
;
255 if ((tfsExt
.ActiveProjectContext
.DomainUri
== null) || (tfsExt
.ActiveProjectContext
.ProjectUri
== null))
257 MessageBox
.Show("Error");
265 private void btn1_Click(object sender
, EventArgs e
)
267 //check whether the value in tb1 is integer
269 bool isInteger
= int.TryParse(tb1
.Text
, out workitemID
);
270 if (!isInteger
|| workitemID
<= 0)
272 MessageBox
.Show("Work Item ID must be an integer and lager than 0");
278 TeamFoundationServerExt tfsExt
= this.GetTFSExt();
279 //chech whether tfsExt exists
282 DocumentService witDocumentService
= (DocumentService
)DTE2
.DTE
.GetObject(
283 "Microsoft.VisualStudio.TeamFoundation.WorkItemTracking.DocumentService");
284 //create a TFS instance with the url
285 TeamFoundationServer activeTFS
= new TeamFoundationServer(
286 tfsExt
.ActiveProjectContext
.DomainUri
);
287 IWorkItemDocument widoc
= null;
288 widoc
= witDocumentService
.GetWorkItem(activeTFS
, workitemID
, this);
291 //Open the work item in Visual Studio
292 witDocumentService
.ShowWorkItem(widoc
);